package io.dy.custom;

import io.dy.util.Lambda;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author : dmj
 * @date: 2024/12/18 4:43 下午
 * @description: 重写PriorityQueue 利用小/大顶堆结合stream实现查询大数据量的最大/小前N个对象值
 */
public class MyQueue<E> extends PriorityQueue<E> {
    /**
     * 设置容量 也就是想保留前 capacity 个值
     */
    private final int capacity;

    //提供一个构造器 供传比较器与容量数据
    public MyQueue(Comparator<? super E> comparator, int capacity) {
        super(comparator);
        this.capacity = capacity;
    }

    @Override
    public boolean offer(E e) {
        boolean b = super.offer(e);
        //判断容量大小
        if(this.size() > capacity){
            //移除堆顶数据
            this.poll();
        }
        return b;
    }


    public static void main(String[] args) {

        System.out.println("开始构建集合...." + new Date());
        List<Integer> list = new ArrayList<>();
        Random random = new Random();
        for (int i = 0; i < 10000000; i++) {
            list.add(random.nextInt(100000000));
        }
        System.out.println("构建集合结束...." + new Date());

        System.out.println("=========================先排序后取值方式===============================");

        System.out.println("\t 开始查询出集合中数值最大的前十个数 ...." + new Date());
        List<Integer> top10 = list.stream().sorted(Comparator.<Integer, Integer>comparing(Function.identity()).reversed()).limit(10).collect(Collectors.toList());
        System.out.println("\t" + top10);
        System.out.println("\t 结束查询出集合中数值最大的前十个数 ...." + new Date());


        System.out.println("=========================小顶堆方式===============================");

        System.out.println("\t 开始查询出集合中数值最大的前十个数 ...." + new Date());
        List<Integer> list1 = new ArrayList<>();
        MyQueue<Integer> collect = list.stream().collect(
                () -> new MyQueue<>(Comparator.comparing(Function.identity()), 10),
                MyQueue::offer,
                (q1, q2) -> {
                }
        );

        MyQueue<Integer> collect1 = list.stream().collect(Lambda.top(Function.<Integer>identity()));

        while (!collect1.isEmpty()){
            list1.add(collect1.poll());
        }
        System.out.println("\t" + list1);
        System.out.println("\t 结束查询出集合中数值最大的前十个数 ...." + new Date());





//        MyQueue<Integer> queue = new MyQueue<>(Comparator.comparing(Function.identity()), 5);
//        queue.offer(1);
//        queue.offer(2);
//        queue.offer(3);
//        queue.offer(4);
//        queue.offer(5);
//        queue.offer(6);
//        queue.offer(100);
//        queue.offer(1090);
//        queue.offer(90);
//        queue.offer(800);
//
//        while (!queue.isEmpty()){
//            System.out.println(queue.poll());
//        }
    }
}
